#include <stdlib.h>
#include <assert.h>

#include "result.h"
#include "mylog.h"

result * result_new(slab * slabp)
{
	result * p = (result *)malloc(sizeof(struct result));
	if(p == NULL){
		return NULL;
	}
	p->slabp = slabp;
	p->off = 0;
	p->next = NULL;
	INIT_LIST_HEAD(&p->result_list);
	return p;
}

int result_free(result * p)
{
	if(p == NULL){
		return -1;
	}
	p->slabp = NULL;
	p->off = 0;
	p->next = NULL;
	INIT_LIST_HEAD(&p->result_list);
	free(p);
	return 0;
}

static tok * tok_new(slab *p, unsigned short len)
{
	assert(p != NULL && len != 0);
	tok * t = slab_alloc(p, sizeof(struct tok), SLAB_TOK);
	if(t == NULL){
		return NULL;
	}
	t->len = len;
	return t;
}

int result_push(result * p, unsigned short len)
{
	assert(p != NULL && len != 0);
	tok * t = tok_new(p->slabp, len);
	if(t == NULL){
		return -1;
	}
	list_add_tail(&t->list, &p->result_list);
	return 0;
}

unsigned short result_next(result * p, unsigned int * offp)
{
	assert(p != NULL);
	if(p->next == NULL){
		p->off = 0;
		p->next = p->result_list.next;
	}
	if(p->next == &p->result_list){
//		p->next = NULL;
		return 0;
	}
	tok * t = list_entry(p->next, tok, list);
	if(t == NULL){
		return 0;
	}
	assert(t != NULL && t->len > 0);
	*offp = p->off;

	p->off += t->len;
	p->next = t->list.next;
	return t->len;
}

int result_clear(result * p)
{
	if(p == NULL){
		return -1;
	}
	p->off = 0;
	p->next = NULL;
	INIT_LIST_HEAD(&p->result_list);
	slab_clear(p->slabp, sizeof(struct tok), SLAB_TOK);
	return 0;
}

